﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Principal;
using EnCor.ObjectBuilder;

namespace EnCor.Security
{
    [AssembleConfig(typeof(WindowsAuthenticationProviderConfig))]
    public class WindowsAuthenticationProvider :AuthenticationProvider
    {
        const string STR_AuthenticationType = "WindowsAuthentication";

        private IList<string> _groups;
        public WindowsAuthenticationProvider(string[] groups)
        {
            if (groups == null)
            {
                throw new ArgumentNullException("groups");
            }

            _groups = new List<string>(groups);
        }

        public override UserIdentity Authenticate(Credential credential)
        {
            if (credential == null)
            {
                throw new ArgumentNullException("credential");
            }
            WindowsCredential windowsCredential = credential as WindowsCredential;
            if (windowsCredential == null)
            {
                throw new InvalidAuthenticationProviderException(string.Format("Current authentication does support the credential type {0}", credential));
            }

            WindowsIdentity windowsIdentity = new WindowsIdentity(windowsCredential.Identity.Token);

            if (!windowsIdentity.IsAuthenticated)
            {
                return null;
            }

            IdentityReferenceCollection groups = windowsIdentity.Groups.Translate(typeof(NTAccount));

            foreach (IdentityReference group in groups)
            {
                if (_groups.Contains(group.Value))
                {
                    return BuildIdentity(windowsIdentity);
                }
            }

            return null;

        }

        private UserIdentity BuildIdentity(WindowsIdentity identity)
        {
            return new UserIdentity(identity.Name, identity.Name);
        }

        public override string CredentialType
        {
            get { return CredentialTypes.WindowsCredential; }
        }
    }
}
